package com.lagou.cloud.gateway.filter;

import com.lagou.cloud.gateway.feign.UserServiceFeignClient;
import com.lagou.common.util.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Component
@Slf4j
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {

    @Autowired
    private UserServiceFeignClient userServiceFeignClient;

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }

    public AuthGatewayFilterFactory() {
        super(Config.class);
        log.info("Loaded GatewayFilterFactory [CustomerGatewayFilterFactory]");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            if (!config.isEnabled()) {
                return chain.filter(exchange);
            }

            ServerHttpRequest serverHttpRequest = exchange.getRequest();
            ServerHttpResponse serverHttpResponse = exchange.getResponse();

            MultiValueMap<String, HttpCookie> cookies = serverHttpRequest.getCookies();
            HttpCookie cookie = cookies.toSingleValueMap().get("token");

            if (cookie != null && "token".equals(cookie.getName())) {
                String token = cookie.getValue();
                if (CommonUtils.isNotBlank(token)) {
                    String email = userServiceFeignClient.info(token);
                    if (CommonUtils.isNotBlank(email)) {
                        return chain.filter(exchange);
                    }
                }
            }

            String message = "没有访问权限，请重新登录";
            log.warn(message);
            serverHttpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
            DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(message.getBytes());
            return serverHttpResponse.writeWith(Mono.just(buffer));
        };
    }

    public static class Config {
        /**
         * 控制是否开启
         */
        private boolean enabled;

        public Config() {}

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}